]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
messageTray: Avoid notification double destruction after activation
authorSebastian Keller <skeller@gnome.org>
Thu, 5 Mar 2026 12:04:37 +0000 (13:04 +0100)
committerSebastian Keller <skeller@gnome.org>
Thu, 5 Mar 2026 14:05:12 +0000 (15:05 +0100)
The activation handler of a notification may indirectly have already
destroyed it before `activate()` continues and tries to destroy it.

This happened for example in the `FdoNotificationDaemon` activation
handler when no default actions are specified, which ends up calling
`destroyNonResidentNotifications()`.

Another case where this could happen is the `WindowAttentionHandler`
which activates the window and upon activation of the window destroys
the entire notification source, which also destroys the notification.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5421
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/4113>

js/ui/messageTray.js

index d4f7cded8c8c7add88fb988cd062c65dd7cc7792..e593d0da715bf0fb30958cfbb2a89789ec88e1b0 100644 (file)
@@ -467,8 +467,14 @@ export class Notification extends GObject.Object {
     }
 
     activate() {
+        console.assert(!this._destroyed, 'Activating a destroyed notification');
+
         this.emit('activated');
 
+        // Avoid double destruction after activation
+        if (this._destroyed)
+            return;
+
         // We don't hide a resident notification when the user invokes one of its actions,
         // because it is common for such notifications to update themselves with new
         // information based on the action. We'd like to display the updated information
@@ -482,6 +488,8 @@ export class Notification extends GObject.Object {
     destroy(reason = NotificationDestroyedReason.DISMISSED) {
         this.emit('destroy', reason);
 
+        this._destroyed = true;
+
         if (this._updateDatetimeId)
             GLib.source_remove(this._updateDatetimeId);
         delete this._updateDatetimeId;